﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
using namespace std;


// 多态条件
// 1、使用基类指针或基类对象调用虚函数
// 2、被调用的函数必须是虚函数，且派生类必须对基类的虚函数进行重写
// 
// 重写：三同——返回值类型相同，函数名相同，参数列表相同
//	     一个在子类中，一个在基类中
//	     协变（特殊）—— 返回值类型可以不同，父类返回父类的指针或引用，子类返回子类的指针或引用

//class Person
//{
//public:
//	virtual void BuyTicket()//虚拟函数
//	{
//		cout << "买票全价" << endl;
//	}
//};
//
//class Student : public Person
//{
//public:
//	virtual void BuyTicket()
//	{
//		cout << "买票半价" << endl;
//	}
//};
//
//void func(Person& p)
//{
//	p.BuyTicket();
//}
//
//int main()
//{
//	/*Person p;
//	p.BuyTicket();
//
//	Student st;
//	st.BuyTicket();
//	st.Person::BuyTicket();*/
//	
//
//	Person p;
//	Student s;
//	func(p);
//	func(s);
//
//
//	return 0;
//}


//class Person {
//public:
//	virtual ~Person() { cout << "~Person()" << endl; }
//	//~Person() { cout << "~Person()" << endl; }
//
//};
//class Student : public Person {
//public:
//	virtual ~Student() { cout << "~Student()" << endl; }
//	//~Student() { cout << "~Student()" << endl; }
//private:
//	int* a = new int[10];
//};
//
//int main()
//{
//	Person* p1 = new Person;
//	Person* p2 = new Student;
//
//	delete p1;
//	delete p2;
//
//
//	return 0;
//}


//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Base::Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Base::Func2()" << endl;
//	}
//
//private:
//	int _b = 1;
//};
//
//
//class Derive : public Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}
//
//	virtual void Func5()
//	{
//		cout << "Derive::Func5()" << endl;
//	}
//private:
//	int _d = 2;
//};
//
//void func(Base& b)
//{
//	b.Func1();
//}
//
//int main()
//{
//	Base b;
//	Derive d;
//	/*b.Func4();
//	d.Base::Func4();*/
//	/*func(b);
//	func(d);*/
//
//	d.Func5();
//	d.Func1();
//	d.Func2();
//
//	return 0;
//}


//class Base {
//public:
//	virtual void func1() { cout << "Base::func1" << endl; }
//	virtual void func2() { cout << "Base::func2" << endl; }
//private:
//	int a;
//};
//class Derive :public Base {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//	virtual void func4() { cout << "Derive::func4" << endl; }
//private:
//	int b;
//};
//
//typedef void (*f)();
//
//void printVFT(f* table)
//{
//	for (int i = 0; table[i] != nullptr; i++)
//	{
//		cout << table[i] << "->";
//		table[i]();
//		cout << endl;
//	}
//}


//int main()
//{
//
//	Base b;
//	Derive d;
//
//	int ptr1 = *((int*)&d);
//	printVFT((f*)ptr1);
//
//	return 0;
//}

//class Base {
//public:
//	virtual void func1() { cout << "Base::func1" << endl; }
//	void func2() { cout << "Base::func2" << endl; }
//	virtual void func3() { cout << "Base::func3" << endl; }
//
//private:
//	int a;
//};
//class Derive :public Base {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	void func2() { cout << "Derive::func2" << endl; }
//private:
//	int b;
//};
//
//void func(Base& b)
//{
//	b.func3();
//}
//
//int main()
//{
//
//	Base b;
//	Derive d;
//	func(b);
//	func(d);
//
//	return 0;
//}



//class Base1 {
//public:
//	virtual void func1() { cout << "Base1::func1" << endl; }
//	virtual void func2() { cout << "Base1::func2" << endl; }
//private:
//	int b1;
//};
//class Base2 {
//public:
//	virtual void func1() { cout << "Base2::func1" << endl; }
//	virtual void func2() { cout << "Base2::func2" << endl; }
//private:
//	int b2;
//};
//class Derive : public Base1, public Base2 {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//private:
//	int d1;
//};
//
//typedef void (*f)();
//
//void printVFT(f* table)
//{
//	for (int i = 0; table[i] != nullptr; i++)
//	{
//		cout << table[i] << "->";
//		table[i]();
//		cout << endl;
//	}
//}
//
//void Print(Base1& b)
//{
//	b.func1();
//}

//int main()
//{
//	Base1 b1;
//	Base2 b2;
//	Derive d;
//
//	int p1 = *((int*)&d);
//	printVFT((f*)p1);
//	cout << "------------------------" << endl;
//	Base2* pb2 = &d;
//	int p2 = *((int*)pb2);
//	printVFT((f*)p2);
//
//	return 0;
//}

//int main()
//{
//
//	Derive d1;
//	Derive d2;
//
//
//	/*int ptr1 = *((int*)&d);
//	printVFT((f*)ptr1);
//
//	Base2* ptr = &d;
//	int ptr2 = *((int*)ptr);
//	printVFT((f*)ptr2);*/
//
//	/*Base1* ptr1 = &d;
//	Base2* ptr2 = &d;
//	ptr1->func1();
//	ptr2->func1();*/
//
//
//	return 0;
//}



//class A
//{
//public:
//	A() :m_iVal(0) 
//	{ 
//		test(); 
//	}
//	virtual void func() 
//	{ 
//		std::cout << m_iVal << ""; 
//	}
//	void test() 
//	{ 
//		func(); 
//	}
//
//public:
//	int m_iVal;
//};
//
//class B : public A
//{
//public:
//	B() 
//	{ 
//		test(); 
//	}
//	virtual void func()
//	{
//		++m_iVal;
//		std::cout << m_iVal << " ";
//	}
//};
//
//int main()
//{
//	A* p = new B;
//	p->test();
//	return 0;
//}


//class A
//{
//public:
//    virtual void f()
//    {
//        cout << "A::f()" << endl;
//    }
//};
//
//class B : public A
//{
//private:
//    virtual void f()
//    {
//        cout << "B::f()" << endl;
//    }
//};
//
//int main()
//{
//    B b;
//
//    A* pa = (A*)new B;
//    pa->f();
//    return 0;
//}
//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Func2()" << endl;
//	}
//	void Func3()
//	{
//		cout << "Func3()" << endl;
//	}
//private:
//	int _b = 1;
//};

//class Derive : public Base
//{
//public:
//	/*virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}*/
//private:
//	int _d = 2;
//};
//void print(Base& b)
//{
//	b.Func1();
//}
//int main()
//{
//	//cout << sizeof(Base) << endl;
//	Base b;
//	Derive d;
//	print(b);
//	print(d);
//
//
//	return 0;
//}


//class A
//{
//public:
//
//    A() :m_iVal(0) { test(); }
//    virtual void func() { std::cout << m_iVal << " "; }
//    void test() { func(); }
//public:
//    int m_iVal;
//};
//
//
//class B : public A
//{
//public:
//    B() { test(); }
//    virtual void func()
//    {
//        ++m_iVal;
//        std::cout << m_iVal << " ";
//    }
//};
//int main(int argc, char* argv[])
//{
//    A* p = new B;
//    p->test();
//    return 0;
//}


//class A
//{
//public:
//	virtual void func1() = 0;
//	
//};
//
//class B : public A
//{
//public:
//	virtual void func1()
//	{
//		cout << "B::func1()" << endl;
//	}
//};
//
//int main()
//{
//	B b;
//	b.func1();
//	return 0;
//}


//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//private:
//	int _b = 1;
//};
//
//int main()
//{
//	Base b;
//	cout << sizeof(Base) << endl;
//	return 0;
//}

//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Base::Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Base::Func2()" << endl;
//	}
//	void Func3()
//	{
//		cout << "Base::Func3()" << endl;
//	}
//private:
//	int _b = 1;
//};
//class Derive : public Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}
//private:
//	int _d = 2;
//};
//
//int main()
//{
//	Base b;
//	Derive d;
//	return 0;
//}


//class Base {
//public:
//	virtual void func1() { cout << "Base::func1" << endl; }
//	virtual void func2() { cout << "Base::func2" << endl; }
//private:
//	int a;
//};
//class Derive :public Base {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//	virtual void func4() { cout << "Derive::func4" << endl; }
//private:
//	int b;
//};
//
//typedef void (*f)();
//
//void printVFT(f* table)
//{
//	for (int i = 0; table[i] != nullptr; i++)
//	{
//		cout << table[i] << "->";
//		table[i]();
//		cout << endl;
//	}
//}
//
//
//int main()
//{
//
//	Base b;
//	Derive d;
//
//	int ptr1 = *((int*)&d);
//	printVFT((f*)ptr1);
//
//	return 0;
//}

//class A
//{
//public:
//    virtual void f()
//    {
//        cout << "A::f()" << endl;
//    }
//};
//
//class B : public A
//{
//private:
//    virtual void f()
//    {
//        cout << "B::f()" << endl;
//    }
//};
//
//int main()
//{
//    B b;
//    A* pa = (A*)new B;
//    pa->f();
//    return 0;
//}

//class A
//{
//public:
//	virtual void x()
//	{
//		cout << "A::x()" << endl;
//	}
//};
//class B : public A
//{
//public:
//	virtual void x()
//	{
//		cout << "B::x()" << endl;
//	}
//};
//int main()
//{
//	B b;
//	b.x();
//	return 0;
//}


class A {
public:
	A(const char* s) { cout << s << endl; }
	~A() {}
};
class B :virtual public A
{
public:
	B(const char* s1, const char* s2) :A(s1) { cout << s2 << endl; }
};
class C :virtual public A
{
public:
	C(const char* s1, const char* s2) :A(s1) { cout << s2 << endl; }
};
class D :public B, public C
{
public:
	D(const char* s1, const char* s2, const char* s3, const char* s4) 
		:B(s1, s2)
		, C(s1, s3)
		, A(s1)
	{
		cout << s4 << endl;
	}
};
int main() {
	D* p = new D("class A", "class B", "class C", "class D");
	delete p;
	return 0;
}